package org.example.java.util.concurrency.data_structure;//: concurrency/ListComparisons.java
// {Args: 1 10 10} (Fast verification check during build)
// Rough comparison of thread-safe List performance.

import org.example.util.CountingIntegerList;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ListComparisons {
  static abstract class ListTest extends Tester<List<Integer>> {
    ListTest(String testId, int nReaders, int nWriters) {
      super(testId, nReaders, nWriters);
    }

    class Reader extends TestTask {
      long result = 0;

      void test() {
        for (long i = 0; i < testCycles; i++)
          for (int index = 0; index < containerSize; index++)
            result += testContainer.get(index);
      }

      void putResults() {
        readResult += result;
        readTime += duration;
      }
    }

    class Writer extends TestTask {
      void test() {
        for (long i = 0; i < testCycles; i++)
          for (int index = 0; index < containerSize; index++)
            testContainer.set(index, writeData[index]);
      }

      void putResults() {
        writeTime += duration;
      }
    }

    void startReadersAndWriters() {
      for (int i = 0; i < nReaders; i++)
        exec.execute(new Reader());
      for (int i = 0; i < nWriters; i++)
        exec.execute(new Writer());
    }
  }

  static class SynchronizedArrayListTest extends ListTest {
    List<Integer> containerInitializer() {
      return Collections.synchronizedList(new ArrayList<Integer>(new CountingIntegerList(containerSize)));
    }

    SynchronizedArrayListTest(int nReaders, int nWriters) {
      super("Synched ArrayList", nReaders, nWriters);
    }
  }

  static class CopyOnWriteArrayListTest extends ListTest {
    List<Integer> containerInitializer() {
      return new CopyOnWriteArrayList<Integer>(new CountingIntegerList(containerSize));
    }

    CopyOnWriteArrayListTest(int nReaders, int nWriters) {
      super("CopyOnWriteArrayList", nReaders, nWriters);
    }
  }


  public static void main(String[] args) {
    Tester.initMain(args);
    new SynchronizedArrayListTest(10, 0);
    new SynchronizedArrayListTest(9, 1);
    new SynchronizedArrayListTest(5, 5);
    new CopyOnWriteArrayListTest(10, 0);
    new CopyOnWriteArrayListTest(9, 1);
    new CopyOnWriteArrayListTest(5, 5);
    Tester.exec.shutdown();
  }
} /* Output: (Sample)
Type                             Read time     Write time
Synched ArrayList 10r 0w      232158294700              0
Synched ArrayList 9r 1w       198947618203    24918613399
readTime + writeTime =        223866231602
Synched ArrayList 5r 5w       117367305062   132176613508
readTime + writeTime =        249543918570
CopyOnWriteArrayList 10r 0w      758386889              0
CopyOnWriteArrayList 9r 1w       741305671      136145237
readTime + writeTime =           877450908
CopyOnWriteArrayList 5r 5w       212763075    67967464300
readTime + writeTime =         68180227375
*///:~
